package logic

import (
	"context"

	"probe-users/internal/errorx"
	"probe-users/internal/svc"
	"probe-users/internal/utils"
	"probe-users/pb/users"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type LoginLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
	return &LoginLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *LoginLogic) Login(in *users.LoginRequest) (*users.LoginResponse, error) {
	// 参数验证
	if err := l.validateLoginParams(in); err != nil {
		return nil, err
	}

	// 查询用户
	user, err := l.svcCtx.UserModel.FindByUsername(in.Username)
	if err != nil {
		return nil, errors.Wrapf(err, "查询用户失败: %s", in.Username)
	}

	// 验证密码
	if !utils.CheckPassword(in.Password, user.Password) {
		return nil, errorx.ErrInvalidPassword
	}

	// 获取角色名称
	role, err := l.svcCtx.RoleModel.FindOne(user.RoleID)
	if err != nil {
		return nil, errors.Wrapf(err, "查询角色失败: %d", user.RoleID)
	}

	// 生成Token
	token, err := utils.GenerateToken(
		user.ID,
		user.Username,
		user.RoleID,
		l.svcCtx.Config.JWTAuth.AccessSecret,
		l.svcCtx.Config.JWTAuth.AccessExpire,
	)
	if err != nil {
		return nil, errors.Wrapf(err, "生成token失败")
	}

	return &users.LoginResponse{
		Id:       user.ID,
		Username: user.Username,
		Token:    token,
		RoleName: role.Name,
	}, nil
}

func (l *LoginLogic) validateLoginParams(in *users.LoginRequest) error {
	if in.Username == "" {
		return errorx.ErrUsernameNotEmpty
	}
	if in.Password == "" {
		return errorx.ErrPasswordNotEmpty
	}
	return nil
}
